package com.yanfan.zutai.util;


import com.yanfan.common.core.domain.BaseEntity;
import com.yanfan.common.utils.SecurityUtils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class EntityUtil {

    private static String[] LIFECYCLE_FIELDS = {"creator", "createTime", "updater", "updateTime"};


    public static <T> void setCreatAndUpdatInfo(T entity) {
        setCreateInfo(entity);
        setUpdateInfo(entity);
    }

    public static <T> void setCreateInfo(T entity) {
        if (null == entity) return;

        if (entity instanceof BaseEntity) {
            ((BaseEntity) entity).setCreateTime(DateUtilLocal.now());
            ((BaseEntity) entity).setCreateBy(SecurityUtils.getUsername());
        }
    }

    public static <T> void setUpdateInfo(T entity) {
        if (null == entity) return;

        if (entity instanceof BaseEntity) {
            ((BaseEntity) entity).setUpdateTime(DateUtilLocal.now());
            ((BaseEntity) entity).setUpdateBy(SecurityUtils.getUsername());
        }
    }

    public static <E, T> T mapping(E source, T target) {
        BeanUtil.copy(source, target);
        return target;
    }

    public static <E, T> T mapping(E source, Class<T> clazz) {
        return BeanUtil.copy(source, clazz);
    }

    public static <E, T> List<T> mapping(List<E> entities, Class<T> clazz) {
        List<T> targetEntities = new ArrayList<T>();
        if (Detect.notEmpty(entities)) {
            for (E entity : entities) {
                targetEntities.add(BeanUtil.copy(entity, clazz));
            }
        }
        return targetEntities;
    }

    public static <T> T mapping(T entity, Map<String, Object> values) {
        if (Detect.notEmpty(values)) {
            Iterator<String> iterator = values.keySet().iterator();
            while (iterator.hasNext()) {
                String field = iterator.next();
                if (ReflectionUtil.hasField(entity, field) && null != values.get(field)) {
                    ReflectionUtil.invokeSetter(entity, field, values.get(field));
                }
            }
        }
        return entity;
    }

    public static <T> void setFieldValues(T entity, Map<String, Object> values) {
        if (Detect.notEmpty(values)) {
            Iterator<String> iterator = values.keySet().iterator();
            while (iterator.hasNext()) {
                String field = iterator.next();
                if (ReflectionUtil.hasField(entity, field) && null != values.get(field)) {
                    ReflectionUtil.invokeSetter(entity, field, values.get(field));
                }
            }
        }
    }

    public static <T> void setFieldValues(T entity, String[] fields, Object[] value) {
        for (int i = 0; i < fields.length; i++) {
            String field = fields[i];
            if (ReflectionUtil.hasField(entity, field)) {
                ReflectionUtil.invokeSetter(entity, field, value[i]);
            }
        }
    }

    //合并两个对象的值
    public static <T> T mergeObjects(T sourceBean, T targetBean) {

        Class sourceBeanClass = sourceBean.getClass();
        Class targetBeanClass = targetBean.getClass();

        Field[] sourceFields = sourceBeanClass.getDeclaredFields();
        Field[] targetFields = sourceBeanClass.getDeclaredFields();
        for (int i = 0; i < sourceFields.length; i++) {
            Field sourceField = sourceFields[i];
            Field targetField = targetFields[i];
            sourceField.setAccessible(true);
            targetField.setAccessible(true);

            Class<?> type = sourceField.getType();

            try {
                if (Detect.notNull(sourceField.get(sourceBean))) {
                    targetField.set(targetBean, sourceField.get(sourceBean));
                }
            } catch (IllegalArgumentException | IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return targetBean;
    }
}
